perm filename BAIL.DOC[DOC,AIL]8 blob sn#158787 filedate 1975-05-12 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00012 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002
C00003 00003
C00004 00004					This is a test program, run on TENEX.
C00006 00005
C00013 00006					Leap and records, DEC TOPS-10 system.
C00015 00007
C00017 00008					Go back to the earlier examle
C00019 00009				I. Compile-time action
C00026 00010				II. Run-time action
C00036 00011				III.  Resources Used
C00038 00012				IV. Current Status
C00040 ENDMK
C⊗;










			BAIL -- A debugger for SAIL








			John F. Reiser
			Computer Science Department
			Stanford University





			May 10, 1975






This work  was supported  in part  by a  National Science  Foundation
graduate  fellowship.    Computer  facilities  provided  by  Stanford
Artificial Intelligence  Laboratory  and Institute  for  Mathematical
Studies in the Social Sciences, Stanford. 




				BAIL



	BAIL is a debugging  aid for SAIL programs.   In may respects
BAIL is  like DDT or RAID, except that  BAIL is oriented towards SAIL
and knows about SAIL data types, primitive operations,  and procedure
implementation.  In  addition, BAIL can display text  from the source
file corresponding to the current location in the program. 

	The first portion  of this manual contains  several annotated
examples  which  illustrate  the mechanics  of  using  BAIL, and  the
features which are available.   Technical details are covered in  the
second part of the manual. 
				This is a test program, run on TENEX.

@TYPE TEST1.SAI

;  <REISER>TEST1.SAI;1   SAT 10-MAY-75 2:37PM         PAGE 1


BEGIN "TEST"
EXTERNAL PROCEDURE BAIL;

INTEGER I,J,K;
STRING A,B,C;
REAL X,Y,Z;
INTEGER ARRAY FOO[0:15]; STRING ARRAY STRARR[1:5,2:6];
INTEGER ITEMVAR DAY; ITEMVAR QQ;

INTEGER PROCEDURE ADD(INTEGER I,J); BEGIN "ADD"
OUTSTR("
HI. GLAD YOU STOPPED BY."); RETURN(I+J) END "ADD";

RECURSIVE INTEGER PROCEDURE FACT(INTEGER N); BEGIN "FACT"
RETURN(IF N LEQ 1 THEN 1 ELSE N*FACT(N-1)) END "FACT";

SIMPLE PROCEDURE SIMPROC(REFERENCE INTEGER M); BEGIN "SBEG"
ADD(M,M←32) END "SBEG";

FOR I←0 STEP 1 UNTIL 15 DO FOO[I]←I*I;
FOR I←1 STEP 1 UNTIL 5 DO
    FOR J←2 STEP 1 UNTIL 6 DO
        STRARR[I,J]←64+8*I+J;
I←4; J←6; K←112;
A←"BIG DEAL"; B←"QED"; C←"THE LAST PICASSO";

X←3.14159265; Y←0; Z←23.;

BAIL;

ADD(7,45);
SIMPROC(J);

USERERR(0,1,"THIS IS A TEST");

END "TEST";

↑L

				Compile and load with BAIL.


@SAIL.SAV;10
 TENEX SAIL 8.1 4-4-75  (? FOR HELP)
*TEST1,←
**/27B
**
TEST1.SAI;1 1
END OF COMPILATION.
LOADING

LOADER 6+9K CORE
EXECUTION

↑C

				Save the core image for later use.

@SSAVE (PAGES FROM) 0 (TO) 577 (ON) TEST1 [NEW FILE]
 [CONFIRM] 

				Start the program.
@START
				BAIL identifies itself
BAIL VER. 10-MAY-75
				and the files involved.
TEST1.SM1;2
  TEST1.SAI;1
END OF BAIL INITIALIZATION.

1:45;
				The "1:" is BAIL's prompt.
				It indicates the level of
				recursive invocations of BAIL.

				See how constants are entered
				and printed.  The "45;<cr>"
				is typed by the user, and
				the next line "45" is BAIL's reply.
   45
1:7.089;
    7.089000    
1:"SOME RANDOM STRING";
   "SOME RANDOM STRING"
				An octal constant; all printout is decimal.
1:'275;
   189
				Symbolic constants
1:TRUE;
   -1
1:FALSE;
   0
1:NULL;
   ""
				Variables
1:I;
   4
				More than one expression requested
1:J,X;
   6    3.141593    
				Assignment
1:I←46;
   46
1:I;
   46
				Relational operators; remember 0 is FALSE.
1:I<J;
   0
1:I GEQ J;
   -1
1:98 LAND '17;
   2
				An undeclared identifier
1:XYZ;

UNKNOWN ID:  XYZ
		;

				Usable as a desk calculator
1:45*(89.4-53.06);
    1635.300    
1:X+J;
    9.141593    
				Function call
1:ADD(3,4);

HI. GLAD YOU STOPPED BY.   7
				Argument list checking
1:ADD(3);

ADD TAKES 2 ARGUMENTS.:  ADD(3)
			       ;

				Arrays
				Array name only gives dimension and
				subscript bounds information.
1:FOO;
   <ARRAY>[ 0:15]
1:FOO[4];
   16
				Substring notation has been extended
				to cover array elements.
1:FOO[5 FOR 3];
   25   36   49
1:STRARR;
   <ARRAY>[ 1:5 2:6]
1:STRARR[1 FOR 2, 4 TO 6];
   "L"   "M"   "N"   "T"   "U"   "V"
				Array accesses are interpreted
1:FOO[35];

SUBSCRIPTING ERROR.   INDEX    VALUE    MIN    MAX
                        1       35      0       15      :  FOO[35]
								  ;

				LENGTH, LOCATION, and MEMORY
1:LENGTH(A);
   8
1:A;
   "BIG DEAL"
1:I;
   46
1:LOCATION(I);
   718
1:MEMORY[718];
   46
1:MEMORY[718]←64;
   64
1:I;
   64
				Substringing
1:A[2 TO INF];
   "IG DEAL"
1:B[3 TO 4];
   "D"
				Type-in must be terminated by a semicolon
1:B
;
   "QED"
				Tracing of procedure entry and exit
1:TRACE("FACT");

1:FACT(4);

 ENTERING FACT   4
  ENTERING FACT   3
   ENTERING FACT   2
    ENTERING FACT   1
    EXITING FACT=   1

   EXITING FACT=   2

  EXITING FACT=   6

 EXITING FACT=   24
   24
1:UNTRACE("FACT");

1:FACT(5);
   120
				Breakpointing
1:BREAK("ADD");

1:ADD(3,4);

				Now one level deeper in BAIL recusion.
				ARGS prints the arguments list.
2:ARGS;
   3   4
				Parameter names evaluate just like variables.
2:I;
   3
2:J;
   4
2:K;
   112
				To exit from one level of BAIL
2:!!GO;

HI. GLAD YOU STOPPED BY.   7
				The message is from ADD itself;
				the value 7 is from BAIL.

				Leave another level of BAIL.
1:!!GO;

				And come back again.  Where are we?
1:TEXT;

				Static block structure
LEXICAL SCOPE, TOP DOWN:
$RUN$
TEST
ADD

				Dynamic procedure invocations
				The #4 means coordinate number 4.
DYNAMIC SCOPE, MOST RECENT FIRST:
ROUTINE         TEXT
ADD     #4      INTEGER PROCEDURE ADD(INTEGER I,J); BEGI
TEST    #24     ADD(7,45);
SIMPROC(J);

USERERR(0,1,"

1:ARGS;
   7   45
				Remove the breakpoint.
1:UNBREAK("ADD");

1:!!GO;

				Output from other calls in the program
HI. GLAD YOU STOPPED BY.
HI. GLAD YOU STOPPED BY.
THIS IS A TEST
CALLED FROM 642124  LAST SAIL CALL AT 400303
↑B
				Entry to BAIL from the error handler
1:TEXT;

LEXICAL SCOPE, TOP DOWN:
$RUN$

DYNAMIC SCOPE, MOST RECENT FIRST:
ROUTINE         TEXT
.SIMPLE.        '642124 %%% FILE NOT VIEWABLE
TEST    #26     USERERR(0,1,"THIS IS A TEST");

END "T

1:I;

UNKNOWN ID:  I
	      ;

				The static scope needs to be set
				back one on the dynamic chain.
1:SETLEX(1);

LEXICAL SCOPE, TOP DOWN:
$RUN$
TEST

1:I;
   64
1:C;
   "THE LAST PICASSO"
1:!!GO;

END OF SAIL EXECUTION
				Leap and records, DEC TOPS-10 system.
.TYPE TEST2.SAI

BEGIN "TEST"
EXTERNAL PROCEDURE BAIL;
REQUIRE 500 SYSTEM!PDL, 10 PNAMES;

LIST L; SET S,S1,S2,S3,S4,S5;
INTEGER ITEM SUNDAY; ITEM MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,
        SATURDAY;
INTEGER ITEMVAR DAY; ITEMVAR QQ;
ITEMVAR ARRAY P[1:10];

RECORD!CLASS CELL (RECORD!POINTER(CELL) CAR,CDR);
RECORD!POINTER(CELL) CX,CY;

CX←NEW!RECORD(CELL);
CY←NEW!RECORD(CELL);
CELL:CAR[CX]←NULL!RECORD; CELL:CDR[CX]←NULL!RECORD;
CELL:CAR[CY]←CX; CELL:CDR[CY]←NULL!RECORD;

P[1]←SUNDAY; P[2]←MONDAY;
L←{{SUNDAY}}; DATUM(SUNDAY)←0; DAY←SUNDAY;  QQ←MONDAY; S←{QQ};
S1←{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
S2←{MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY};
S3←{MONDAY,WEDNESDAY,FRIDAY}; S4←{SATURDAY,SUNDAY};
S5←{SUNDAY,FRIDAY};

FOREACH DAY SUCH THAT DAY IN S1 DO MAKE DAY XOR SUNDAY EQV SATURDAY;

BAIL;

USERERR(0,1,"THIS IS A TEST");

END "TEST";


EXIT
↑C
.EXECUTE TEST2.SAI(27B,)
SAIL: TEST2  1
LOADING
LOADER 15K CORE
25K MAX 153 WORDS FREE
EXECUTION

BAIL VER. 10-MAY-75
TEST2.SM1
  TEST2.SAI
END OF BAIL INITIALIZATION.

1:L;
   {{SUNDAY}}
1:S1;
   {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}
1:S2;
   {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY}
1:S1 INTER S2;
   {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY}
1:S4;
   {SUNDAY, SATURDAY}
1:S5;
   {SUNDAY, FRIDAY}
1:S4 UNION S5;
   {SUNDAY, FRIDAY, SATURDAY}
1:FRIDAY IN S4;
   0
1:FRIDAY IN S5;
   -1
1:S2<S1;
   -1
1:S2<S2;
   0
1:S2 LEQ S2;
   -1
1:DAY;
   SATURDAY
1:DAY←SUNDAY;
   SUNDAY
1:DATUM(DAY);
   0
1:CX;
   CELL.9231
1:CELL:CAR[CX];
   NULL!RECORD
1:CELL:CDR[CX];
   NULL!RECORD
1:CELL:CAR[CY];
   CELL.9231
1:SUNDAY ASSOC SATURDAY;
   {SUNDAY}
1:SUNDAY EQV SATURDAY;
   {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}
1:SUNDAY XOR SATURDAY;
   PHI
1:SUNDAY EQV SUNDAY;
   PHI
1:↑C
				Go back to the earlier examle
@TEST1.SAV;1

				Initialization uses file created
				last time.
BAIL VER. 10-MAY-75 USING TEST1.BAI
END OF BAIL INITIALIZATION.

				Switch /27B at compile-time
				makes SAIL predeclared runtime
				routines known to BAIL.
1:OPENFILE(NULL,"W");
TODAY.TMP
   4
1:OUT(4,"THIS IS A TEMPORARY FILE CREATED WHILE IN BAIL.");

1:CFILE(4);
   -1
1:OPENFILE("","RC");
TODAY.TMP [OLD VERSION]
   4
1:SINI(4,200,"Z");
   "THIS IS A TEMPORARY FILE CREATED WHILE IN BAIL."
1:ODTIM(-1,-1);
   "SATURDAY, MAY 10, 1975 17:19:29"

				Quickie review of BAIL capabilities
1:?

EXPRESSION;
PROCEDURE!CALL;
TRACE("PROCEDURE");
UNTRACE("PROCEDURE");
BREAK("PROCEDURE, BLOCK, OR LABEL");
UNBREAK("PROCEDURE, BLOCK, OR LABEL");
!!GO;
SETLEX(LEVEL);
TEXT;
ARGS;
HELP;
DDT;
?

1:!!GO;

HI. GLAD YOU STOPPED BY.
HI. GLAD YOU STOPPED BY.
THIS IS A TEST
CALLED FROM 642124  LAST SAIL CALL AT 400303
↑

END OF SAIL EXECUTION
@

				End of the examples.

			I. Compile-time action

	The principal  result of activating  BAIL at  compile-time is
the generation of  a file of information about the source program for
use by the run-time interpreter.  This file has the same name  as the
.REL file produced  by the compilation, except that  the extension is
.SM1.  If requested, BAIL will also generate some additional code for
SIMPLE  procedures  to make  them  more  palatable  to  the  run-time
interpreter. 

	The action of BAIL  at compile time is governed  by the value
of the /B switch passed to the compiler.  If the value of this switch
is  zero (the  default  if  no  value  is  specified)  then  BAIL  is
completely  inactive.   Otherwise, the  low-order bits  determine the
actions  which  BAIL  performs.   [The  value  of  the  /B  switch is
interpreted as octal.]

	bit	action

	 1	If this bit  is on, then  the .SM1 file  will contain
		the program counter to source/listing text directory.  

	 2	If this bit  is on, then  the .SM1 file  will contain
		symbol  information for all  SAIL symbols encountered
		in the source.  If this bit is  off, then information
		is kept only for  procedures, parameters, blocks, and
		internals;  i.e., non-  internal local  variables are
		not recorded. 

	 4	If this  bit is on,  then SIMPLE procedures  will get
		procedure descriptors, and one additional instruction
		(a  JFCL  0,  which  is  the  fastest  machine  no-op
		instruction) is  inserted at the beginning  of SIMPLE
		procedures.    Except  for  these  two  changes,  all
		properties of  SIMPLE procedures remain  the same  as
		before.  The procedure descriptor is necessary if the
		procedure is to  be called interpretively  or if  the
		procedure is to be TRACEd. 

	'10	If  this   bit  is   on,  then   BAIL  will  not   be
		automatically  loaded and  initialized,  although all
		other actions  requested  are  performed.    This  is
		primarily  intended to  make it  easier to  debug new
		versions    of   BAIL    without   interfering   with
		SYS:BAIL.REL.  By using this switch the decision to
		load BAIL is delayed until load time.

	'20	If  this   bit  is  on,   then  a  request   to  load
		SYS:BAIPDn.REL  is  generated.    This file  contains
		procedure  descriptors   for   most   of   the   SAIL
		predeclared runtime  routines, making it  possible to
		call  them from BAIL.   The procedure descriptors and
		their symbols occupy about 6K. 

The B switch must occur on the binary term, not the listing or source
term.  Thus:
	.R SAIL			or	.COM PROG(27B,)
	*PROG/27B←PROG


	The program counter to source/listing index  is kept in terms
of coordinates.  The coordinate counter is zeroed at the beginning of
the compilation and is incremented  by one for each BEGIN, ELSE,  and
semicolon seen by the parser, provided  at least one word of code has
been  compiled since the previous coordinate  was defined.  Note that
COMMENTs are  seen only  by the  scanner,  not the  parser, and  that
DEFINEs and many declarations  merely define symbols and do not cause
instructions to  be generated.   For  each coordinate  the  directory
contains the coordinate number, the value of the program counter, and
a  file pointer to the  appropriate place.  The  appropriate place is
the source file unless a listing file is being produced and  the CREF
switch is  off, in which case  it is the listing  file.  [The listing
file produced  for CREF is nearly unreadable.] On a non-CREF listing,
the program counter is replaced by the coordinate number  if bit 1 of
the /B switch is on. 

	The symbol table information consists  of the block structure
and the name, access information, and type for each symbol. 

	If a BEGIN-END pair  has declarations (i.e., is a  true block
and  not just a  compound statement) but  does not have  a name, then
BAIL will invent one.   The name is of  the form Bnnnn where nnnn  is
the decimal value of the current coordinate. 
			II. Run-time action

        The BAIL run-time interpreter is itself a  SAIL program which
resides  on the  system disk  area.  This  program is  usually loaded
automatically, and  does  some initialization  when entered  for  the
first time. 

	The  initialization  generates a  .BAI  file  of  information
collected from  the .SM1 files produced  by separate compilations (if
any).  The  .SM1 files correspond  to .REL files,  and the .BAI  file
corresponds to the .DMP or .SAV file.  Like RPG or CCL, BAIL will try
to bypass much of the initialization and use an existing .BAI file if
appropriate.  During  initialization BAIL displays  the names of  the
.SM1  files it  is  processing.  For each  .SM1  file which  contains
program counter/text index  information, BAIL displays  the names  of
the text files and determines whether the text files are accessable. 

	The interpreter  is  activated by  explicit call,  previously
inserted  breakpoints, or the  SAIL error  handler.  For  an explicit
call, say  EXTERNAL  PROCEDURE  BAIL;  ... BAIL;.    From  the  error
handler,  respond B.   Breakpoints  will be  described later  in this
section. 

        Debugging Requests.  When entered,  BAIL prints the debugging
recursion level followed by a colon, and awaits a debugging request. 
Options which are available are

	<expression not involving AND, OR, IF-THEN-ELSE, or CASE>;
	<procedure!call>;
	TRACE("procedure");
	UNTRACE("procedure");
	BREAK("procedure, block, or label");
	UNBREAK("procedure, block, or label");
	!!GO;
	SETLEX(level);
	TEXT;
	ARGS;
	HELP;
	DDT;
	?

        Expressions and procedure calls are evaluated as  if they had
appeared  in the  source  file at  the point  of  the break.   TRACE,
UNTRACE, BREAK, and UNBREAK handle breakpoint insertion and deletion.
!!GO resumes execution  of the program.  SETLEX allows  access to the
static  environment of dynamic ancestors.   TEXT displays the current
static and dynamic scopes,  with text from the original  source file.
ARGS prints the arguments to the most recently called procedure.  DDT
transfers control to an assembly  language debugging program (if  one
was loaded).  HELP and "?" both print the above list. 

	Breakpoints.  Breakpoints are handled by evaluating a call to
one of four procedures defined inside BAIL. 

	procedure		description

TRACE("proc name")		Prints  the procedure  name  at  each
				entry  and  exit,  the parameters  at
				entry, and  the  value  RETURNed  (if
				any) at exit. 

UNTRACE("proc name")		Discontinues tracing of the procedure.

BREAK("location")		Plants a breakpoint (a  call to BAIL)
				at location, which may be a procedure,
				label, or block name.

UNBREAK("location")		Remove a breakpoint.


	
	Naming conventions:  Names defined within the current lexical
(static) scope are always recognized.  After that, objects with names
that are globally unique and have a fixed memory location (everything
except parameters and recursive locals) are recognized.  After that,
BAIL gives up.

	Extended specification  of location names:
In case the desired location is not unique, the following extended
syntax may be used.

	location := label | procedure | blockname delim location

where delim is  any non-identifier character (e.g.,  altmode, period,
,virgule,space,...).  The last blockname should be the block in which
the label or procedure is delared.  The complete search algorithm is:
Search the blocks in memory-location order of BEGINs until a block is
found  which has  the first  blockname as  its name.   If there  is a
second   blockname,   continue  the   search   of   the   blocks   in
memory-location  order, beginning  with the  block  which immediately
follows the block which matched the first blockname.  Continue  until
all blocknames  have been  matched.   This yields  some block in  the
program.  Construct  the block structure ancestry of that block.  The
label or procedure must then be  declared within the scope of one  of
the blocks of that ancestry. 

	Examining variables  not in  the current  lexical scope:  The
procedure  SETLEX(n) changes the  lexical scope  to the scope  of the
n-th entry in the dynamic scope list.  SETLEX(0) is the scope  of the
breakpoint; SETLEX(1) is the scope  of the most recent procedure call
in the dynamic scope; etc. 

	BAIL and DDT:  If BAIL is  initialized in a core  image which
does  not have DDT or  RAID, then things  will be set up  so that the
monitor command DDT gets  you into BAIL in the  right way.  That  is,
BAIL will be your DDT.  To enter BAIL from DDT, use

	pushi P,<address which BAIL should take as the program counter>$X
	JRST BAIL$X

For example, if .JBOPC contains the program counter,

	PUSH P,.JBOPC$X
	JRST BAIL$X

To enter DDT from BAIL, simply say  DDT;.

	Syntax  extension:  The  TO and  FOR  substring  and  sublist
operators  have been extended  to operate as  array subscript ranges,
FOR PRINT-OUT ONLY.  Thus if FOO is an array, then FOO[3  TO 7]; will
act like  FOO[3], FOO[4],  FOO[5], FOO[6], FOO[7];  but is  easier to
type.  This extension is for print-out only; no general APL syntax or
semantics are provided. 

WARNING: Since BAIL  is itself a  SAIL procedure, entering  BAIL from
the  error handler  or DDT  after  a push-down  overflow or  a string
garbage collection error will get you into trouble. 


	BAIL and SIMPLE procedures: SIMPLE procedures cause headaches
for  BAIL because they do  not keep a display  pointer.  [Indeed, the
compiler gets lost in the following example, and does not complain:

	BEGIN "LOST"
	PROCEDURE A(INTEGER I); BEGIN "A"
		SIMPLE PROCEDURE B; OUTSTR("THE VALUE OF I IS " & CVS(I));
		PROCEDURE C(INTEGER J); B;
	C(2);
	END "A";

	A(1);
	END "LOST";							]

BAIL tries valiantly to do the right  thing, but occasionally it also
gets lost.  BAIL will try to warn you if it can.  In general, looking
at value string parameters of SIMPLE procedures does not work. 
			III.  Resources Used

A.  Compile-time

    1.	One channel.  This means that REQUIREd source files may only be
	nested to a depth of about 9.

    2.	Memory.  Upto 11*(maximum lexical nesting depth) more words of
	memory may be required compared with previous compilations.

    3.	CPU time.  Approximately 0.3 seconds per page of dense text.

B.  Run-time

    1.	Channels.  Three during initialization, two thereafter.  Channels
	are obtained via GETCHAN.

    2.	BAIL uses 7 of the privile7ged breaktables, obtaining them by GETBREAK.

    3.	REQUIRE 64 STRING!PDL.  Necessary if the debugging recursion
	level will exceed 3 or 4.

    4.	Memory.  (9.5K +((# of coordinates+127) DIV 128) + (2* # of blocks) +
	(5* # of symbols)) words.

    5.	CPU time.

	a.  Initialization.  Typically 4 seconds for a 30 page program.

	b.  Debugging requests.  0.07 seconds per simple request.
	    DDT response time.

C.  Disk space

    1.  The .SM1 file for a /7B compilation is typically one-fourth the
	size of	the corresponding .REL file.

    2.	The .BAI file for a group of /7B compilations is typically
	one-third the total size of the corresponding .REL files.
			IV. Current Status



    The state of the world is determined by the values of the accumulators
    and the value of the SAIL varaible !SKIP!.

    The run-time interpreter recognizes only the first 15 characters of
    identifier names; the rest are discarded without comment.  The
    characters which are legal in identifiers are

	ABCDEFGHIJKLMNOPQRSTUVWXYZ
	abcdefghijklmnopqrstuvwxyz
	0123456789!_αβπλ⊂⊃∀∃→~#$\|

	Notable for its absence: period.

    LOCATION of a procedure does not work.

    PROPS is read-only.

    Bracketed triple items are not allowed.

    Functional arguments are not handled correctly.

    Contexts are not recognized.

    The run-time interpreter will not recognize macros.